﻿using Prism.Events;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Xcj.Mes.WholeLine.DataBase.Entity;
using Xcj.Mes.WholeLine.DataBase.Service;
using Xcj.Mes.WholeLine.Plc.Events;

namespace Xcj.Mes.WholeLine.ZH.HG.Shell.ViewModels.Alarm
{
    public class AlarmViewModel : BaseViewModel
    {
        private string _deviceType = string.Empty;
        public string DeviceType 
        {
            get => _deviceType;
            set
            {
                _deviceType = value;
                RaisePropertyChanged();
            }
        }
        
        private Dictionary<string, AlarmConfigEntity> _dicAlarmConfigEntity = new Dictionary<string, AlarmConfigEntity>();
        public Dictionary<string, AlarmConfigEntity> DicAlarmConfigEntity
        {
            get => _dicAlarmConfigEntity;
            set
            {
                _dicAlarmConfigEntity = value;
                RaisePropertyChanged();
            }
        }
        
        private Dictionary<string, int> _dicAlarmTimes = new Dictionary<string, int>();
        public Dictionary<string, int> DicAlarmTimes
        {
            get => _dicAlarmTimes;
            set
            {
                _dicAlarmTimes = value;
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<AlarmEntity> _alarmEntities = new ObservableCollection<AlarmEntity>();
        public ObservableCollection<AlarmEntity> AlarmEntities
        {
            get => _alarmEntities;
            set
            {
                _alarmEntities = value;
                RaisePropertyChanged();
            }
        }

        private SubscriptionToken _subscriptionToken;

        public AlarmViewModel(string deviceType)
        {
            Init(deviceType);
            _subscriptionToken = _eventAggregator?.GetEvent<PlcDataEvent>()?.Subscribe(OnPlcData);
        }

        private void Init(string deviceType)
        {
            DeviceType = deviceType?.Trim();
            
            if (string.IsNullOrEmpty(DeviceType)) return;
            
            using(AlarmConfigService service = new AlarmConfigService())
            {
                var alarmConfigEntities = service?.All()?.Where(o=>o.DeviceType == DeviceType)?.OrderBy(o=>o.Address)?.ToList();
                if(alarmConfigEntities != null)
                {
                    foreach (var alarmEntity in alarmConfigEntities)
                    {
                        if(DicAlarmConfigEntity.ContainsKey(alarmEntity.Address))
                            DicAlarmConfigEntity.Remove(alarmEntity.Address);
                        DicAlarmConfigEntity.Add(alarmEntity.Address, alarmEntity);

                        if (DicAlarmTimes.ContainsKey(alarmEntity.Address))
                            DicAlarmTimes.Remove(alarmEntity.Address);
                        DicAlarmTimes.Add(alarmEntity.Address, 0);
                    }
                }
            }
        }

        private void OnPlcData((string DeviceType, string address, string value) args)
        {
            string deviceType = args.DeviceType?.Trim();
            string address    = args.address?.Trim();
            string value      = args.value?.Trim()?.ToLower();

            // 处理接收到的事件
            if ((string.IsNullOrEmpty(deviceType)) 
                || (string.IsNullOrEmpty(address)) 
                || (string.IsNullOrEmpty(value)) 
                || (deviceType != DeviceType)) 
                return;
            
            if (!DicAlarmConfigEntity.ContainsKey(address)) 
                return;
            
            bool isAlarm = false;

            if (value == "true") isAlarm = true;
            else if (value == "false") isAlarm = false;
            else return;

            AlarmConfigEntity alarmConfigEntity = DicAlarmConfigEntity[address];
            
            if (alarmConfigEntity.IsAlarm == isAlarm) return;
            
            if (isAlarm)
            {
                AlarmEntity alarmEntity = new AlarmEntity();
                alarmEntity.DeviceSn      = App.deviceConfigEntity.DeviceSn; // 机台编码
                alarmEntity.DeviceType    = deviceType;                      // 设备类型
                alarmEntity.AlarmAddress  = address;                         // 报警地址
                alarmEntity.AlarmCode     = alarmConfigEntity.Code;          // 报警代码
                alarmEntity.AlarmContent  = alarmConfigEntity.Content;       // 报警内容
                alarmEntity.StartTime     = DateTime.Now;                    // 开始时间
                alarmEntity.StopTime      = DateTime.Now;                    // 结束时间
                alarmEntity.AlarmDuration = 0;                               // 报警时长
                DicAlarmTimes[address]++;                                    
                alarmEntity.AlarmTimes = DicAlarmTimes[address];             // 报警次数
                AlarmEntities.Add(alarmEntity);
            }
            else
            {
                var alarmEntity = AlarmEntities?.Where(o => o.AlarmAddress == address)?.OrderByDescending(o => o.StartTime)?.FirstOrDefault();
                if (alarmEntity != null)
                {
                    alarmEntity.StopTime = DateTime.Now;
                    alarmEntity.AlarmDuration = (alarmEntity.StopTime.Value - alarmEntity.StartTime).TotalMilliseconds;
                    using(AlarmService service = new AlarmService())
                        try { service.Add(alarmEntity); } catch { }
                }
            }
            alarmConfigEntity.IsAlarm = isAlarm;
        }

        public override sealed void Dispose()
        {
            // 取消订阅
            try { if (_subscriptionToken != null) _eventAggregator.GetEvent<PlcDataEvent>().Unsubscribe(_subscriptionToken); } catch { }

            // 发布事件
            //_eventAggregator.GetEvent<MyEvent>().Publish(new MyEventArgs { Message = message });
        }
    }
}
